package com.userdemo.demo.service.base.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.userdemo.demo.annotation.SysLog;
import com.userdemo.demo.base.BaseService;
import com.userdemo.demo.common.sys.ServerResponse;
import com.userdemo.demo.constant.base.Const;
import com.userdemo.demo.entity.base.BaseUser;
import com.userdemo.demo.entity.base.BaseUserMenu;
import com.userdemo.demo.entity.base.dto.BaseUserDTO;
import com.userdemo.demo.entity.base.vo.BaseUserVO;
import com.userdemo.demo.enumeration.base.DataStatusEnum;
import com.userdemo.demo.enumeration.base.UseTypeEnum;
import com.userdemo.demo.enumeration.base.YesOrNoEnum;
import com.userdemo.demo.enumeration.sys.ResponseCode;
import com.userdemo.demo.service.base.IBaseUserService;
import com.userdemo.demo.util.base.MD5Util;
import com.userdemo.demo.util.base.NumberUtil;
import com.userdemo.demo.util.base.StringUtil;
import com.xiaoleilu.hutool.http.HttpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 　　* @description: 用户服务层
 * 　　* @param ${tags}
 * 　　* @return ${return_type}
 * 　　* @throws
 * 　　* @author 陈宇
 * 　　* @date $date$ $time$
 *
 */
@Service("iBaseUserService")
public class BaseUserServicerImpl extends BaseService implements IBaseUserService {

    @Autowired
    private RedisTemplate redisTemplate;



    /**
     * 用户登录
     *
     * @param userName
     * @param password
     * @return
     */
    @SysLog("用户登录")
    @Override
    public ServerResponse<BaseUserVO> login(String userName, String password) {
        // 检测用户名是否存在
        int resultCount = baseUserMapper.countNumByUserName(userName);
        if(resultCount == 0){
            return ServerResponse.createByErrorMessage("用户名不存在");
        }
        // 加密密码
        String md5Password = MD5Util.MD5EncodeUtf8(password);
        BaseUserVO baseUser = baseUserMapper.selectLogin(userName,md5Password);
        if(null == baseUser){
            return ServerResponse.createByErrorMessage("密码错误");
        }
        if(null == baseUser.getStatus() || null == baseUser.getIsIn()){
            return ServerResponse.createByErrorMessage("用户数据异常，请联系网站人员");
        }
        if(DataStatusEnum.INVALID.getCode() == baseUser.getStatus().intValue()){
            return ServerResponse.createByErrorMessage("该账户已失效");
        }
        if(YesOrNoEnum.NO.getCode() == baseUser.getIsIn().intValue()){
            return ServerResponse.createByErrorMessage("该用户已离职");
        }
        return ServerResponse.createBySuccess("登录成功",baseUser);
    }

    /**
     * 新增/更新用户
     *
     * @param baseUserDTO
     * @return
     */
    @Override
    public ServerResponse<String> addOrUpdateUser(BaseUserDTO baseUserDTO,BaseUserVO baseUserVO) {
        if(null == baseUserDTO || StringUtil.isEmpty(baseUserDTO.getUserName())){
            return ServerResponse.createByErrorMessage("参数错误");
        }
        boolean isAdd = false;
        BaseUser baseUser = null;
        if(null != baseUserDTO.getUserId() && 0 < baseUserDTO.getUserId()){
            baseUser = baseUserMapper.selectByPrimaryKey(baseUserDTO.getUserId());
        }else{
            //新增用户，判断用户名是否存在
            if(baseUserMapper.countNumByUserName(baseUserDTO.getUserName()) > 0){
                return ServerResponse.createByErrorMessage("用户名已存在");
            }
        }
        if(null == baseUser){
            if(StringUtil.isEmpty(baseUserDTO.getPassword())){
                return ServerResponse.createByErrorMessage("请输入密码");
            }
            baseUser = new BaseUser();
            isAdd = true;
            //新增才可修改用户名和创建人
            baseUser.setUserName(baseUserDTO.getUserName());
            baseUser.setCreateUser(baseUserVO.getUserName());
            //默认生效和在职
            baseUser.setStatus(DataStatusEnum.NORMAL.getCode());
            baseUser.setIsIn(YesOrNoEnum.YES.getCode());
        }
        baseUser.setDisplayName(baseUserDTO.getDisplayName());
        if(StringUtil.isNotEmpty(baseUserDTO.getPassword())){
            baseUser.setPassword(MD5Util.MD5EncodeUtf8(baseUserDTO.getPassword()));
        }
        baseUser.setEmail(baseUserDTO.getEmail());
        baseUser.setPhone(baseUserDTO.getPhone());
        baseUser.setRoleId(baseUserDTO.getRoleId());
        baseUser.setOrgId(baseUserDTO.getOrgId());
        baseUser.setCreateOrgId(baseUserVO.getCreateOrgId());
        baseUser.setCreateTopOrgId(baseUserVO.getCreateTopOrgId());
        baseUser.setRemark(baseUserDTO.getRemark());
        baseUser.setSex(baseUserDTO.getSex());
        if(baseUserVO.getUseType().intValue() == UseTypeEnum.PLATFORM.getCode()){
            //公司ID(如果是平台用就可以设置其他的公司ID)
            baseUser.setCompanyId(baseUserDTO.getCompanyId());
            baseUser.setUseType(baseUserDTO.getUseType());
        }else{
            //公司ID
            baseUser.setCompanyId(baseUserVO.getCompanyId());
            baseUser.setUseType(baseUserVO.getUseType());
        }
        if(!isAdd){
            baseUser.setStatus(baseUserDTO.getStatus());
            baseUser.setIsIn(baseUserDTO.getIsIn());
        }
        baseUser.setUpdateUser(baseUserVO.getUserName());
        baseUser.setUpdateTime(new Date());
        if(isAdd){
            baseUser.setId(baseUserMapper.selectSeq());
            baseUser.setStatus(YesOrNoEnum.YES.getCode());
            baseUser.setIsIn(YesOrNoEnum.YES.getCode());
            baseUser.setVersion(Const.INITPAGENUM);
            baseUser.setCreateTime(new Date());
            baseUserMapper.insert(baseUser);
        }else{
            baseUserMapper.updateByPrimaryKeySelective(baseUser);
        }
        //菜单ID集合
        saveUserMenu(baseUser.getUserName(),baseUserDTO.getMenuIds(),baseUserVO);
        return ServerResponse.createBySuccessMessage("操作成功");
    }

    /**
     * 获取请求用户
     *
     * @param request
     * @return
     */
    @Override
    public BaseUserVO getRequestUser(HttpServletRequest request) {
        //获取缓存用户信息
        String loginToken = request.getParameter(Const.LOGINTOKEN);
        if(StringUtil.isEmpty(loginToken)){
            return null;
        }
        Object oUser =  redisTemplate.opsForValue().get(loginToken);
        BaseUserVO user = null;
        if(null != oUser) {
            user = (BaseUserVO) oUser;
        }
        if(null == user){
            return null;
        }
        return user;
    }

    /**
     * 根据ID删除用户
     *
     * @param baseUserDTO
     * @param baseUserVO
     * @return
     */
    @Override
    public ServerResponse<String> delUserById(BaseUserDTO baseUserDTO, BaseUserVO baseUserVO) {
        if(null == baseUserDTO || null == baseUserVO){
            return ServerResponse.createByErrorMessage("参数错误");
        }
        //如果不是平台用户则判断权限
        if(baseUserVO.getUseType().intValue() != UseTypeEnum.PLATFORM.getCode()){
            baseUserDTO.setCompanyId(baseUserVO.getCompanyId());
        }
        //更新用户为失效状态
        if(baseUserMapper.updateUserStatusById(baseUserDTO.getUserId(),baseUserVO.getCompanyId()) > 0){
            return ServerResponse.createBySuccessMessage("删除成功");
        }
        return ServerResponse.createByErrorMessage("删除失败");
    }

    /**
     * 查询用户列表
     *
     * @param baseUserDTO
     * @param baseUserVO
     * @return
     */
    @Override
    public ServerResponse<PageInfo> selectListUser(BaseUserDTO baseUserDTO, BaseUserVO baseUserVO) {
        if(null == baseUserDTO || null == baseUserVO){
            return ServerResponse.createByErrorMessage("参数错误");
        }
        if(null == baseUserDTO.getPageNum()){
            baseUserDTO.setPageNum(Const.INITPAGENUM);
        }
        if(null == baseUserDTO.getPageSize()){
            baseUserDTO.setPageSize(Const.INITPAGESIZE);
        }
        //如果不是平台用户则判断权限
        if(baseUserVO.getUseType().intValue() != UseTypeEnum.PLATFORM.getCode()){
            baseUserDTO.setCompanyId(baseUserVO.getCompanyId());
        }
        PageHelper.startPage(baseUserDTO.getPageNum(),baseUserDTO.getPageSize(),true,false,null);
        List<BaseUserVO> list = baseUserMapper.selectListUser(baseUserDTO);
        if(null == list){
            return ServerResponse.createByErrorMessage("没有数据");
        }
        return ServerResponse.createBySuccess("查询成功",new PageInfo(list));
    }

    /**
     * 查询单个用户详情
     *
     * @param baseUserDTO
     * @param baseUserVO
     * @return
     */
    @Override
    public ServerResponse<BaseUserVO> selectUpdateUserInfoById(BaseUserDTO baseUserDTO, BaseUserVO baseUserVO) {
        if(null == baseUserDTO || null == baseUserDTO.getUserId() || null == baseUserVO){
            return ServerResponse.createByErrorMessage("参数错误");
        }
        //如果不是平台用户则判断权限
        if(baseUserVO.getUseType().intValue() != UseTypeEnum.PLATFORM.getCode()){
            baseUserDTO.setCompanyId(baseUserVO.getCompanyId());
        }
        BaseUserVO result = baseUserMapper.selectUpdateUserInfoById(baseUserDTO.getUserId(),baseUserDTO.getCompanyId());

        //查询用户角色Id
        List<Long> roleIdList = baseRoleMapper.selectRoleIdByUserName(result.getUserName());
        if(null != roleIdList && 0 < roleIdList.size()){
            //查询用户组织机构数据权限ID
            List<Long> rmIdList = baseRoleMechanismMapper.selectOrgIdListByRoleIds(roleIdList);
            result.setRoldIds(roleIdList);
            result.setRmIds(rmIdList);
        }

        if(null == result){
            return ServerResponse.createByErrorMessage("没有数据");
        }
        return ServerResponse.createBySuccess("查询成功",result);
    }

    /**
     * 查询项目负责人接口
     *
     * @param baseUserDTO
     * @param baseUserVO
     * @return
     */
    @Override
    public ServerResponse<PageInfo> selectProjectLeader(BaseUserDTO baseUserDTO, BaseUserVO baseUserVO) {
        if(null == baseUserDTO || null == baseUserVO){
            return ServerResponse.createByErrorMessage("参数错误");
        }
        if(null == baseUserDTO.getPageNum()){
            baseUserDTO.setPageNum(Const.INITPAGENUM);
        }
        if(null == baseUserDTO.getPageSize()){
            baseUserDTO.setPageSize(Const.INITPAGESIZE);
        }
        PageHelper.startPage(baseUserDTO.getPageNum(),baseUserDTO.getPageSize(),true,false,null);
        List<BaseUserVO> list = baseUserMapper.selectProjectLeader(baseUserVO.getCompanyId());
        if(null == list || 0 == list.size()){
            return ServerResponse.createByErrorMessage("没有数据");
        }
        return ServerResponse.createBySuccess("查询成功",new PageInfo(list));
    }

    /**
     * 用户名注册
     *
     * @param baseUserDTO
     * @return
     */
    @Override
    public ServerResponse<String> userRegistration(BaseUserDTO baseUserDTO) {
        String result = judgementParameter(baseUserDTO);
        if(StringUtil.isNotEmpty(result)){
            return ServerResponse.createByErrorMessage(result);
        }
        BaseUser baseUser = new BaseUser();
        //用户名
        baseUser.setUserName(baseUserDTO.getUserName());
        //密码
        baseUser.setPassword(MD5Util.MD5EncodeUtf8(baseUserDTO.getPassword()));
        //联系人
        baseUser.setDisplayName(baseUserDTO.getDisplayName());
        //手机号
        baseUser.setPhone(baseUserDTO.getPhone());
        //邮箱
        baseUser.setEmail(baseUserDTO.getEmail());
        //供应商用户
        baseUser.setUseType(UseTypeEnum.SUPPLIERS.getCode());
        baseUser.setId(baseUserMapper.selectSeq());
        baseUser.setStatus(YesOrNoEnum.YES.getCode());
        baseUser.setIsIn(YesOrNoEnum.YES.getCode());
        baseUser.setVersion(Const.INITPAGENUM);
        baseUser.setCreateTime(new Date());
        baseUser.setUpdateTime(new Date());
        if(baseUserMapper.insert(baseUser) > 0){
            return ServerResponse.createBySuccessMessage("注册成功");
        }
        return ServerResponse.createByErrorMessage("注册失败，请刷新后重试");
    }

    /**
     * 查询供应商列表
     *
     * @param baseUserDTO
     * @param baseUserVO
     * @return
     */
    @Override
    public ServerResponse<PageInfo> selectSuppliersList(BaseUserDTO baseUserDTO, BaseUserVO baseUserVO) {
        if(null == baseUserDTO || null == baseUserVO){
            return ServerResponse.createByErrorMessage("参数错误");
        }
        if(null == baseUserDTO.getPageNum()){
            baseUserDTO.setPageNum(Const.INITPAGENUM);
        }
        if(null == baseUserDTO.getPageSize()){
            baseUserDTO.setPageSize(Const.INITPAGESIZE);
        }
        PageHelper.startPage(baseUserDTO.getPageNum(),baseUserDTO.getPageSize(),true,false,null);
        List<BaseUserVO> list = baseUserMapper.selectSuppliersList(baseUserDTO);
        if(null == list || 0 == list.size()){
            return ServerResponse.createByErrorMessage("没有数据");
        }
        return ServerResponse.createBySuccess("查询成功",new PageInfo(list));
    }

    /**
     * 注册代理机构用户和医务工作者
     *
     * @param baseUserDTO
     * @return
     */
    @Override
    public ServerResponse<String> userCompanyRegistration(BaseUserDTO baseUserDTO) {
        String result = "";
        if(baseUserDTO.getUseType() != null && baseUserDTO.getUseType() != 0)
        {
            if(baseUserDTO.getUseType() == UseTypeEnum.AC.getCode())
            {
                result = judgementParameter(baseUserDTO);
            }

            if(baseUserDTO.getUseType() == UseTypeEnum.MEDICAL.getCode())
            {
                result = judgementParameterMedical(baseUserDTO);
            }
        }

        if(StringUtil.isNotEmpty(result)){
            return ServerResponse.createByErrorMessage(result);
        }
        BaseUser baseUser = new BaseUser();
        //用户名
        baseUser.setUserName(baseUserDTO.getUserName());
        //密码
        baseUser.setPassword(MD5Util.MD5EncodeUtf8(baseUserDTO.getPassword()));
        //联系人
        baseUser.setDisplayName(baseUserDTO.getDisplayName());
        //手机号
        baseUser.setPhone(baseUserDTO.getPhone());
        //邮箱
        baseUser.setEmail(baseUserDTO.getEmail());
        //供应商用户
        baseUser.setUseType(baseUserDTO.getUseType());
        baseUser.setId(baseUserMapper.selectSeq());
        baseUser.setStatus(YesOrNoEnum.YES.getCode());
        baseUser.setIsIn(YesOrNoEnum.YES.getCode());
        baseUser.setVersion(Const.INITPAGENUM);
        baseUser.setCreateTime(new Date());
        baseUser.setUpdateTime(new Date());
        if(baseUserMapper.insert(baseUser) > 0){
            return ServerResponse.createBySuccessMessage("注册成功");
        }
        return ServerResponse.createByErrorMessage("注册失败，请刷新后重试");
    }

    private String judgementParameterMedical(BaseUserDTO baseUserDTO) {
        if(null == baseUserDTO){
            return "对象为空";
        }
        if(StringUtil.isEmpty(baseUserDTO.getUserName())){
            return "用户名不能为空";
        }
        //判断用户名是否存在
        if(baseUserMapper.countNumByUserName(baseUserDTO.getUserName()) > 0){
            return "用户名已存在";
        }
        if(StringUtil.isEmpty(baseUserDTO.getPassword())){
            return "登录密码不能为空";
        }

        if(StringUtil.isEmpty(baseUserDTO.getPhone())){
            return "手机号不能为空";
        }
        //判断手机号是否存在
        if(baseUserMapper.countNumByPhone(baseUserDTO.getPhone()) > 0){
            return "手机号已存在";
        }
        if(StringUtil.isEmpty(baseUserDTO.getMessgaeCode())){
            return "验证码不能为空";
        }
        //判断验证码是否正确
        String catchCode = StringUtil.valueOfString(redisTemplate.opsForValue()
                .get(baseUserDTO.getPhone()+Const.CodeType.PHONECODE));
        if(!catchCode.equals(baseUserDTO.getMessgaeCode())){
            return "验证码错误或已过期";
        }
        return "";
    }

    /**
     * 用户注册参数判断
     * @param baseUserDTO
     * @return
     */
    String judgementParameter(BaseUserDTO baseUserDTO){
        if(null == baseUserDTO){
            return "对象为空";
        }
        if(StringUtil.isEmpty(baseUserDTO.getUserName())){
            return "用户名不能为空";
        }
        //判断用户名是否存在
        if(baseUserMapper.countNumByUserName(baseUserDTO.getUserName()) > 0){
            return "用户名已存在";
        }
        if(StringUtil.isEmpty(baseUserDTO.getPassword())){
            return "登录密码不能为空";
        }
        if(StringUtil.isEmpty(baseUserDTO.getDisplayName())){
            return "信息申报人不能为空";
        }
        if(StringUtil.isEmpty(baseUserDTO.getPhone())){
            return "手机号不能为空";
        }
        //判断手机号是否存在
        if(baseUserMapper.countNumByPhone(baseUserDTO.getPhone()) > 0){
            return "手机号已存在";
        }
        if(StringUtil.isEmpty(baseUserDTO.getMessgaeCode())){
            return "验证码不能为空";
        }
        //判断验证码是否正确
        String catchCode = StringUtil.valueOfString(redisTemplate.opsForValue()
                .get(baseUserDTO.getPhone()+Const.CodeType.PHONECODE));
        if(!catchCode.equals(baseUserDTO.getMessgaeCode())){
            return "验证码错误或已过期";
        }
        if(StringUtil.isEmpty(baseUserDTO.getEmail())){
            return "联系邮箱不能为空";
        }
        return "";
    }


    /**
     * 保存用户菜单
     * @param menuIds
     * @return
     */
    int saveUserMenu(String userName,String menuIds,BaseUserVO baseUserVO){
        int num = 0;
        if(StringUtil.isNotEmpty(menuIds) && StringUtil.isNotEmpty(userName)){
            String[] menuIdArr = menuIds.split(",");
            //清除用户菜单缓存
            redisTemplate.delete(userName+Const.BASEMENUVO);
            if(null != menuIdArr){
                //先删除该用户的所有菜单
                baseUserMenuMapper.delByUserName(userName);
                for (String menudId : menuIdArr){
                    BaseUserMenu baseUserMenu = new BaseUserMenu();
                    baseUserMenu.setUserName(userName);
                    baseUserMenu.setUseType(baseUserVO.getUseType());
                    baseUserMenu.setMenuId(NumberUtil.safeToLong(menudId,0));
                    if(baseUserMenuMapper.insert(baseUserMenu) > 0){
                        num++;
                    }
                }
            }
        }
        //清空用户菜单缓存
        redisTemplate.delete(baseUserVO.getUserName()+Const.BASEMENUVO);
        return num;
    }
}
